<template>
  <div v-if="props.cascader == '不级联'" style="width: 100%" class="selector">
    <!-- :teleported="false"
      v-loadmore="loadmore"
    -->
    <el-select
      v-model="selectStr"
      @change="selectChange"
      :clearable="props.clearable"
      :placeholder="props.placeholder"
      v-if="checkType(props.type)"
      filterable
      :disabled="props.disabled"
      :style="props.style"
      :class="props.border ? '' : 'selectNoBorder'"
      :multiple="props.multiple"
      collapse-tags
      collapse-tags-tooltip
    >
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      >
        <span v-if="showRight" style="float: left">{{ item.label }}</span>
        <span class="showRight" v-if="showRight">{{ item.code }}</span>
      </el-option>
    </el-select>
    <el-select
      v-else
      v-model="selectList"
      @change="selectChange"
      clearable
      collapse-tags
      collapse-tags-tooltip
      multiple
      :disabled="props.disabled"
      :style="props.style"
    >
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      >
        <span v-if="showRight" style="float: left">{{ item.label }}</span>
        <span class="showRight" v-if="showRight">{{ item.code }}</span>
      </el-option>
    </el-select>
  </div>
  <div v-if="props.cascader == '级联'" style="width: 100%" class="selector">
    <el-tree-select
      v-model="selectStr"
      lazy
      :show-checkbox="props.multiple"
      :multiple="props.multiple"
      :load="treeLoad"
      :props="treeProps"
      collapse-tags
      collapse-tags-tooltip
      :disabled="props.disabled"
      :class="props.modelValue ? 'placeholderColor' : ''"
      ref="treeRef"
      :style="props.style"
      :placeholder="props.placeholder"
      clearable
      @node-click="selectChange"
      @change="handleTreeChange"
    />
  </div>
</template>
<script setup name="Selector">
import useUserStore from '@/store/modules/user.js';

import {
  getCurrentInstance,
  nextTick,
  onMounted,
  reactive,
  ref,
  toRefs,
  watch
} from 'vue';
import { listRole } from '@/api/system/role';
import { listUser } from '@/api/system/user';
import { GetAreaList_Page } from '@/api/school/region';
import { GetSixSalePlanList_Page } from '@/api/sixManage/executionPlan';
import { GetPlaceList_Page } from '@/api/site/index';
import { GetSixSaleTypeList_Page } from '@/api/sixManage/problemType';
import { GetDeviceTypeList_Page } from '@/api/teachDevice/type';
import { GetDeviceList_Page } from '@/api/teachDevice/account.js';
import { GetCourseTypeList_Page } from '@/api/lesson/lessonType';
import { GetCourseList_Page } from '@/api/lesson/lessonSystem';
import { GetClassList_PID, GetClassList } from '@/api/school/class';
import { GetDeptList_PID } from '@/api/school/deptMent';
import { GetSchoolTimeList_Page } from '@/api/school/classHour';
import { GetCertificateList_Page } from '@/api/certificate/index';
import { GetClassBindUserList } from '@/api/school/class.js';
import { GetTypeList_Page } from '@/api/online/type.js';
import Nation from '@/views/components/common/nation';

const { proxy } = getCurrentInstance();
const emit = defineEmits([
  'update:modelValue',
  'getItem',
  'update:placeholder'
]);
const props = defineProps({
  params: {
    default: ''
  },
  showRight: {
    default: true
  },
  cascader: {
    default: '不级联'
  },
  IsEquipmentPos: {
    default: 1
  },
  type: {
    type: String,
    default: 'string'
  },
  modelValue: {},
  category: {
    type: String,
    default: '角色'
  },
  check: {
    default: 1
  },
  query: {
    default: {
      NoPage: true
    }
  },
  placeholder: {
    default: '请选择'
  },
  checkStrictly: {
    default: false
  },
  disabled: {
    default: false
  },
  style: {
    default: ''
  },
  clearable: {
    default: true
  },
  border: {
    default: true
  },
  multiple: {
    default: false
  }
});
const treeRef = ref({});
const treeProps = {
  label: 'label',
  children: 'children',
  isLeaf: 'isLeaf',
  disabled: 'disabled'
};

let data = reactive({
  isLoadmore: false,
  total: 0,
  page: {
    PageIndex: 1,
    PageSize: 99999
  },
  selectStr: '',
  selectList: [],
  options: [],
  look: false
});

let { isLoadmore, total, page, selectStr, selectList, options, look } =
  toRefs(data);
onMounted(() => {
  init();
});

watch(
  () => props.modelValue,
  (n, o) => {
    if (props.type == 'string') {
      selectStr.value = n ? String(n) : '';
      if (props.placeholder != '请选择') {
        selectStr.value = '';
      }
    } else {
      if (!n?.length || !n) return (selectList.value = []);
      selectList.value = n?.map(item => String(item)) || [];
    }
  },
  {
    deep: true,
    immediate: true
  }
);
watch(
  () => props.query,
  (n, o) => {
    if (JSON.stringify(n) == JSON.stringify(o)) return;
    init();
  },
  {
    deep: true
    // immediate: true,
  }
);

async function treeLoad(node, resolve) {
  if (node.isLeaf) return resolve([]);
  const { level } = node;
  let res;
  let ID;
  if (level == 0) {
    ID = 0;
  } else {
    ID = node.data.value;
  }
  nextTick(() => {
    let node = treeRef.value.getNode(selectStr.value);
    if (!node) selectStr.value = '';
  });

  switch (props.category) {
    case '用户级联':
      if (ID == 0 || Number(node.data?.type) < 4) {
        res = await GetClassList_PID({ ID });
        res.data?.forEach(item => {
          if (item.Info.Type != 4 && props.type == 'array') {
            item.disabled = true;
          }
          if (item.Info.Type == 4) {
            item.IsHasChild = true;
          }
        });
      } else {
        res = await GetClassBindUserList({ ID });
        res.data?.forEach(item => {
          item.IsHasChild = false;
        });
      }

      break;
    case '班级级联':
      res = await GetClassList_PID({ ID });
      res.data?.forEach(item => {
        if (item.Info.Type != 4 && props.type == 'array') {
          item.disabled = true;
        }
      });

      break;
    case '部门级联':
      res = await GetDeptList_PID({ ID });
      break;
    case '课程级联':
      if (ID == 0) {
        res = await GetCourseTypeList_Page({ NoPage: 'true' });
      } else {
        res = await GetCourseList_Page({ Type: ID, NoPage: 'true' });
      }
      res.data?.forEach(item => (item.IsHasChild = item.HasChild));
      break;
    case '场地级联':
      if (ID == 0) {
        res = await GetAreaList_Page({ NoPage: 'true' });
        res.data?.forEach(item => {
          item.IsHasChild = true;
        });
      } else {
        res = await GetPlaceList_Page({ ID_Area: ID, NoPage: 'true', Type: 1 });
        res.data?.forEach(item => {
          item.self = {
            IsOccupy: item.IsOccupy
          };
        });
      }

      break;
  }
  res.data = res.data?.map(item => {
    return {
      ...item,
      ...item.Info
    };
  });
  let nodes = res.data?.map(item => {
    return {
      value: item.ID,
      label: item.Name,
      isLeaf: !item.IsHasChild,
      type: item.Type,
      Mode: item.Mode,
      disabled: item.disabled,
      ...item.self
    };
  });

  resolve(nodes);
}

function handleTreeChange(val) {
  if (!val) {
    clearValue();
  } else {
    // emit('update:modelValue', val);
  }
}

const selectChange = val => {
  if (props.cascader == '不级联') {
    if (props.type == 'string') {
      if (!val) {
        emit('update:modelValue', undefined);
        emit('update:placeholder', '请选择');
        emit('getItem', '');
        return;
      }
    } else {
      if (!val.length) {
        emit('update:modelValue', []);
        emit('getItem', '');
        return;
      }
    }
    emit('update:modelValue', val);
    let item = {};
    if (props.multiple) {
      item = options.value.find(
        data => data?.item?.ID && String(data.item?.ID) == String(val.at(-1))
      );
      let all = options.value?.filter(data => {
        return val?.includes(data.item?.ID);
      });
      if (!item) {
        emit('update:modelValue', []);
        emit('getItem', '');
        return;
      } else {
        item.item.all = all;
      }
    } else {
      item = options.value.find(
        data => data?.item?.ID && String(data.item?.ID) == String(val)
      );
    }
    if (props.category == '周月年') {
      let time = [];
      switch (val) {
        case '1':
          time[0] = proxy.$moment().subtract(1, 'week').format('YYYY-MM-DD');
          time[1] = proxy.$moment().format('YYYY-MM-DD');
          break;
        case '2':
          time[0] = proxy.$moment().subtract(1, 'month').format('YYYY-MM-DD');
          time[1] = proxy.$moment().format('YYYY-MM-DD');
          break;
        case '3':
          time[0] = proxy.$moment().subtract(1, 'year').format('YYYY-MM-DD');
          time[1] = proxy.$moment().format('YYYY-MM-DD');
          break;
        default:
          time[0] = '';
          time[1] = '';
          break;
      }
      emit('getItem', time);
    } else {
      emit('getItem', item?.item);
    }
  } else {
    switch (props.category) {
      case '用户级联':
        if (val.type) {
          nextTick(() => {
            clearValue();
          });
        } else {
          emitValue(val);
        }

        break;
      case '班级级联':
        if (props.multiple) {
        } else {
          if (val?.type != 4) {
            nextTick(() => {
              clearValue();
            });
            return;
          } else {
            emitValue(val);
          }
        }
        break;
      case '场地级联':
        console.log(val);
        if (!val?.hasOwnProperty('IsOccupy')) {
          nextTick(() => {
            clearValue();
          });
          return;
        } else {
          console.log(val);
          emitValue(val);
        }
        break;
      case '课程级联':
        if (!val?.Mode) {
          nextTick(() => {
            clearValue();
          });
          return;
        } else {
          emitValue(val);
        }
        break;
      default:
        emitValue(val);
        break;
    }
  }
};

function clearValue() {
  selectStr.value = '';
  emit('update:modelValue', '');
  emit('update:placeholder', '请选择');
  emit('getItem', '');
}
function emitValue(val) {
  emit('update:modelValue', val.value);
  emit('getItem', val);
}
const loadmore = async () => {
  if (look.value) return;
  if (total.value > options.value.length) {
    look.value = true;
    page.value.PageIndex++;
    isLoadmore.value = true;
    await init();
    look.value = false;
  }
};
const init = async () => {
  return new Promise(async (resolve, reject) => {
    switch (props.category) {
      case '网课类型':
        await getOnlineTypeList();
        resolve(1);
        break;
      case '正常':
        await getNormal();
        resolve(1);
        break;
      case '出勤':
        await getAttendance();
        resolve(1);
        break;
      case '民族':
        await getNation();
        resolve(1);
        break;
      case '周月年':
        await getZYN();
        resolve(1);
        break;
      case '全部证书':
        await getAllCertificateList();
        resolve(1);
        break;
      case '角色':
        await getRoleList({ ...page });
        resolve(1);
        break;
      case '班级类型':
        getClassType();
        resolve(1);
        break;
      case '全部班级':
        getAllClass();
        resolve(1);
        break;
      case '全部用户':
        await getAllUserList();
        resolve(1);
        break;
      case '学校区域':
        await getRegionList();
        resolve(1);
        break;
      case '6S执行方案':
        await getSixExecutionPlan();
        resolve(1);
        break;
      case '全部场地':
        await getAllSitePlace();
        resolve(1);
        break;
      case '6S类型':
        await getSixType();
        resolve(1);
        break;
      case '保养方案类型':
        getMaintainType();
        resolve(1);
        break;
      case '设备保养方案':
        getDeviceMaintain();
        resolve(1);
        break;
      case '启用':
        getYesOrNo();
        resolve(1);
        break;
      case '设备自身状态':
        getSelfStatus();
        resolve(1);
        break;
      case '设备过程状态':
        getProcessStatus();
        resolve(1);
        break;
      case '设备类型':
        await getDeviceType();
        resolve(1);
        break;
      case '全部设备':
        await getAllDevice();
        resolve(1);
        break;
      case '课程类型':
        await getCourseType();
        resolve(1);
        break;
      case '全部课程':
        await getAllCourse();
        resolve(1);
        break;
      case '课时方案':
        await getCoursePlan();
        resolve(1);
        break;
      case '用户列表':
        await getUserList();
        resolve(1);
        break;
      case '结果':
        await getResult();
        resolve(1);
        break;
    }
  });
};
async function getOnlineTypeList() {
  try {
    let query = {
      Code: '',
      Name: '',
      NoPage: true,
      ...props.query
    };
    let res = await GetTypeList_Page(query);
    let list = res?.data?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    options.value = list;
  } catch (error) {
    console.log(error);
  }
}
const checkType = () => {
  if (props.type == 'string') {
    return true;
  }
};
//名族
async function getNation() {
  Nation?.forEach(item => (item.value = item.label));
  options.value = Nation;
}
//正常
async function getNormal() {
  options.value = [
    {
      label: '不正常',
      value: '0'
    },
    {
      label: '正常',
      value: '1'
    }
  ];
}
//出勤
async function getAttendance() {
  options.value = [
    {
      label: '未出勤',
      value: '0'
    },
    {
      label: '已出勤',
      value: '1'
    }
  ];
}
//周月年
async function getZYN() {
  options.value = [
    {
      label: '近一周',
      value: '1'
    },
    {
      label: '近一月',
      value: '2'
    },
    {
      label: '近一年',
      value: '3'
    }
  ];
}
//结果
async function getResult() {
  options.value = [
    {
      label: '合格',
      value: '1'
    },
    {
      label: '不合格',
      value: '2'
    }
  ];
}
//获取证书
async function getAllCertificateList() {
  try {
    let query = {
      Code: '',
      Name: '',
      NoPage: true,
      ...props.query
    };
    let res = await GetCertificateList_Page(query);
    let list = res?.data?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    options.value = list;
  } catch (error) {
    console.log(error);
  }
}
//获取班级
async function getAllClass() {
  try {
    let query = {
      Code: '',
      Name: '',
      NoPage: true,
      ...props.query
    };
    let res = await GetClassList(query);
    let list = res?.data?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    options.value = list;
  } catch (error) {
    console.log(error);
  }
}

//获取课时方案
async function getCoursePlan() {
  try {
    let query = {
      Code: '',
      Name: '',
      NoPage: true,
      ...props.query
    };
    let res = await GetSchoolTimeList_Page(query);
    let list = res?.data?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    options.value = list;
  } catch (error) {
    console.log(error);
  }
}
//获取全部课程
async function getAllCourse() {
  try {
    let query = {
      Code: '',
      Name: '',
      NoPage: true,
      ...props.query
    };
    let res = await GetCourseList_Page(query);
    let list = res?.data?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    options.value = list;
  } catch (error) {
    console.log(error);
  }
}
//获取课程类型
async function getCourseType() {
  try {
    let query = {
      Code: '',
      Name: '',
      NoPage: true,
      ...props.query
    };
    let res = await GetCourseTypeList_Page(query);
    let list = res?.data?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    options.value = list;
  } catch (error) {
    console.log(error);
  }
}
//获取所有设备保养方案
async function getDeviceMaintain() {
  // try {
  //   let query = {
  //     ...page.value,
  //     Code: "",
  //     Name: "",
  //     NoPage: true,
  //     ...props.query,
  //   };
  //   let res = await GetDeviceList_Page(query);
  //   let list = res?.data?.map((item) => {
  //     return {
  //       label: item.Name,
  //       value: String(item.ID),
  //       // code: item.code,
  //       item,
  //     };
  //   });
  //   options.value = list;
  // } catch (error) {
  //   console.log(error);
  // }
}
//获取所有设备
async function getAllDevice() {
  try {
    let query = {
      ...page.value,
      Code: '',
      Name: '',
      NoPage: true,
      ...props.query
    };
    let res = await GetDeviceList_Page(query);
    let list = res?.data?.map(item => {
      return {
        label: item.Code,
        value: String(item.ID),
        code: item.Name,
        item
      };
    });
    options.value = list;
  } catch (error) {
    console.log(error);
  }
}
//设备类型
async function getDeviceType() {
  try {
    let query = {
      ...page.value,
      Code: '',
      Name: '',
      NoPage: true,
      ...props.query
    };
    let res = await GetDeviceTypeList_Page(query);
    let list = res?.data?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    options.value = list;
  } catch (error) {
    console.log(error);
  }
}
//过程状态
function getProcessStatus() {
  let type = props.query.Type ? props.query.Type : 1;
  options.value = [
    {
      label: type == 1 ? '正常运行' : '在库',
      value: '1'
    },
    {
      label: type == 1 ? '保养中' : '检验中',
      value: '2'
    },
    {
      label: '维修中',
      value: '3'
    },
    {
      label: '使用中',
      value: '4'
    }
  ];
}
//自身状态
function getSelfStatus() {
  options.value = [
    {
      label: '正常',
      value: '1'
    },
    {
      label: '降级',
      value: '2'
    },
    {
      label: '报废',
      value: '3'
    }
  ];
}
//是否
function getYesOrNo() {
  options.value = [
    {
      label: '启用',
      value: 'Y'
    },
    {
      label: '停用',
      value: 'N'
    }
  ];
}
//保养方案类型
function getMaintainType() {
  options.value = [
    {
      label: '装备',
      value: '1'
    },
    {
      label: '工具',
      value: '2'
    }
  ];
}
//获取场地
async function getAllSitePlace() {
  try {
    let query = {
      Code: '',
      Name: '',
      NoPage: true,
      ...props.query
    };
    let res = await GetPlaceList_Page(query);
    let list = res?.data?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    options.value = list;
  } catch (error) {
    console.log(error);
  }
}
//获取6s方案列表
async function getSixExecutionPlan() {
  try {
    let query = {
      Code: '',
      Name: '',
      NoPage: true,
      ...props.query
    };
    let res = await GetSixSalePlanList_Page(query);
    let list = res?.data?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    options.value = list;
  } catch (error) {
    console.log(error);
  }
}
//获取6s分类
async function getSixType() {
  try {
    let query = {
      Code: '',
      Name: '',
      NoPage: true,
      ...props.query
    };
    let res = await GetSixSaleTypeList_Page(query);
    let list = res?.data?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    options.value = list;
  } catch (error) {
    console.log(error);
  }
}
//获取区域
async function getRegionList() {
  try {
    let query = {
      ...page.value,
      Code: '',
      Name: '',
      NoPage: true,
      ...props.query
    };
    let res = await GetAreaList_Page(query);
    let list = res?.data?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    options.value = list;
  } catch (error) {
    console.log(error);
  }
}
//用户列表
async function getUserList() {
  try {
    let res;
    let query = {
      ...page.value,
      Account: '', //模糊搜素
      Name: '', //模糊搜素
      Phone: '', //模糊搜素
      Type: '', //类型 1:学生 2:职员 3:管理员
      ...props.query
    };

    res = await listUser(query);
    total.value = res.data.Total;
    let list = res?.data?.List?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    if (isLoadmore.value) {
      options.value = [...options.value, ...list];
    } else {
      options.value = list;
    }
  } catch (error) {
    console.log(error);
  }
}
//全部用户
async function getAllUserList() {
  let list = useUserStore().allUserList?.map(item => {
    return {
      label: item.Name,
      value: String(item.ID),
      // code: item.code,
      item
    };
  });
  options.value = list;
}

//获取班级类型
function getClassType() {
  let list = [];
  switch (String(props.query.Type)) {
    case '0':
      list = [
        {
          label: '学年',
          value: '1'
        },
        {
          label: '院系',
          value: '2'
        },
        {
          label: '专业',
          value: '3'
        },
        {
          label: '班级',
          value: '4'
        }
      ];
      break;
    case '1':
      list = [
        {
          label: '院系',
          value: '2'
        },
        {
          label: '专业',
          value: '3'
        },
        {
          label: '班级',
          value: '4'
        }
      ];
      break;
    case '2':
      list = [
        {
          label: '专业',
          value: '3'
        },
        {
          label: '班级',
          value: '4'
        }
      ];
      break;
    case '3':
      list = [
        {
          label: '班级',
          value: '4'
        }
      ];
      break;
  }
  options.value = list;
}

//获取角色列表
const getRoleList = async () => {
  try {
    let res;
    let query = {
      ...page.value,
      ...props.query
    };

    res = await listRole(query);
    total.value = res.data.Total;
    let list = res?.data?.List?.map(item => {
      return {
        label: item.Name,
        value: String(item.ID),
        // code: item.code,
        item
      };
    });
    if (isLoadmore.value) {
      options.value = [...options.value, ...list];
    } else {
      options.value = list;
    }
  } catch (error) {
    console.log(error);
  }
};
</script>
<style lang="scss" scoped>
:deep(.el-select-tags-wrapper) {
  display: flex !important;
  .el-select__tags-text {
    max-width: unset !important;
  }
}
.showRight {
  float: right;
  margin-left: 10px;
  color: #8492a6;
  font-size: 13px;
}
:deep(.placeholderColor) {
  .el-input__inner {
    color: #606266;
    &::placeholder {
      color: #fff;
    }

    &::-webkit-input-placeholder {
      /* WebKit browsers 适配谷歌 */
      color: #606266;
    }

    &:-moz-placeholder {
      /* Mozilla Firefox 4 to 18 适配火狐 */
      color: #606266;
    }

    &::-moz-placeholder {
      /* Mozilla Firefox 19+ 适配火狐 */
      color: #606266;
    }

    &:-ms-input-placeholder {
      /* Internet Explorer 10+  适配ie*/
      color: #606266;
    }
  }
}

:deep(.selectNoBorder) {
  border: none !important;
  --el-select-border-color-hover: #fff;
  .select-trigger {
    border: none !important;
    .el-input {
      --el-input-focus-border: #fff;
      --el-input-transparent-border: 0 0 0 0px;
      --el-input-border-color: #fff;
      --el-input-hover-border: 0px !important;
      --el-input-hover-border-color: #fff;
      --el-input-focus-border-color: #fff;
      --el-input-clear-hover-color: #fff;
      box-shadow: 0 0 0 0px !important;
      --el-input-border: 0px;
      .el-input__inner {
        border: none !important;
        outline: none !important;
      }
    }
  }
  .el-input__wrapper.is-focus {
    box-shadow: 0 0 0 0px !important;
  }
  .el-input.is-focus .el-input__inner {
    box-shadow: 0 0 0 0px !important;
  }
  .el-input__inner:focus {
    box-shadow: 0 0 0 0px !important;
  }
  .el-input.is-focus .el-input__wrapper {
    box-shadow: 0 0 0 0px !important;
  }
}
</style>
